<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.4.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.4/css/all.min.css" integrity="sha256-mUZM63G8m73Mcidfrv5E+Y61y7a12O5mW4ezU3bxqW4=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/animate.css@3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"anynone.gitee.io","root":"/","images":"/images","scheme":"Pisces","darkmode":true,"version":"8.7.1","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":false,"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"}}</script><script src="/js/config.js"></script>
<meta property="og:type" content="website">
<meta property="og:title" content="anynone">
<meta property="og:url" content="https://anynone.gitee.io/page/4/index.html">
<meta property="og:site_name" content="anynone">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="山丘之王">
<meta name="twitter:card" content="summary">


<link rel="canonical" href="https://anynone.gitee.io/page/4/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":true,"isPost":false,"lang":"zh-CN","comments":"","permalink":"","path":"page/4/index.html","title":""}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>anynone</title>
  




  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <h1 class="site-title">anynone</h1>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu">
        <li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a></li>
  </ul>
</nav>




</div>
        
  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>

  <aside class="sidebar">

    <div class="sidebar-inner sidebar-overview-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <img src="/images/head.jpg">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">山丘之王</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap site-overview-item animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">22</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-tags">
        <span class="site-state-item-count">15</span>
        <span class="site-state-item-name">标签</span>
      </div>
  </nav>
</div>
  <div class="links-of-author site-overview-item animated">
      <span class="links-of-author-item">
        <a href="https://github.com/anynone" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;anynone" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
  </div>



        </div>
      </div>
    </div>
  </aside>
  <div class="sidebar-dimmer"></div>


    </header>

    
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


    <div class="main-inner index posts-expand">

    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="https://anynone.gitee.io/2022/04/20/20220420-dockerfile-build/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="山丘之王">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="anynone">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2022/04/20/20220420-dockerfile-build/" class="post-title-link" itemprop="url">Dockerfile编写和镜像构建</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2022-04-20 22:11:21" itemprop="dateCreated datePublished" datetime="2022-04-20T22:11:21+08:00">2022-04-20</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2022-09-09 23:39:18" itemprop="dateModified" datetime="2022-09-09T23:39:18+08:00">2022-09-09</time>
      </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <p>一、 常用Dockerfile指令</p>
<ul>
<li><span style="color:green;">FROM</span> 指定当前镜像构建流程的基础镜像，一般是基于官方linux发行版或其他官方镜像源<h6 id="语法"><a href="#语法" class="headerlink" title="语法:"></a>语法:</h6><span style="color:#8B008B;">FROM</span> <span style="color:#CD5555;">[–platform=&lt;platform&gt;] &lt;image&gt; [AS &lt;name&gt;]</span><h6 id="示例："><a href="#示例：" class="headerlink" title="示例："></a>示例：</h6><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> alpine:latest</span><br></pre></td></tr></table></figure></li>
</ul>
<hr>
<ul>
<li><span style="color:green;">RUN</span>  创建一个容器层，并在当前容器层执行命令<h6 id="语法-1"><a href="#语法-1" class="headerlink" title="语法:"></a>语法:</h6><span style="color:#8B008B;">RUN</span> <span style="color:#CD5555;">&lt;command&gt;</span><h6 id="示例：-1"><a href="#示例：-1" class="headerlink" title="示例："></a>示例：</h6><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">RUN</span><span class="bash"> apk update \</span></span><br><span class="line"><span class="bash">&amp;&amp; apk add nginx</span></span><br></pre></td></tr></table></figure></li>
</ul>
<hr>
<ul>
<li><span style="color:green;">ENV</span>  设置环境变量<h6 id="语法-2"><a href="#语法-2" class="headerlink" title="语法:"></a>语法:</h6><span style="color:#8B008B;">ENV</span> <span style="color:#CD5555;">&lt;key&gt;=&lt;value&gt; …</span><h6 id="示例：-2"><a href="#示例：-2" class="headerlink" title="示例："></a>示例：</h6><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ENV</span> SERVER_NAME=服务名称</span><br><span class="line"><span class="comment"># 一次设置多个</span></span><br><span class="line"><span class="keyword">ENV</span> TITLE=标题 TIMEZONE=<span class="string">&quot;Asia/SangHai&quot;</span></span><br></pre></td></tr></table></figure></li>
</ul>
<hr>
<ul>
<li><span style="color:green;">LABEL</span>  设置镜像元数据标签信息<h6 id="语法-3"><a href="#语法-3" class="headerlink" title="语法:"></a>语法:</h6><span style="color:#8B008B;">LABEL</span> <span style="color:#CD5555;">&lt;key&gt;=&lt;value&gt; &lt;key&gt;=&lt;value&gt; &lt;key&gt;=&lt;value&gt; …</span><h6 id="示例：-3"><a href="#示例：-3" class="headerlink" title="示例："></a>示例：</h6><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">LABEL</span><span class="bash"> SERVER_NAME=“服务名称“</span></span><br><span class="line"><span class="comment"># 设置多个</span></span><br><span class="line"><span class="keyword">LABEL</span><span class="bash"> LABEL1=<span class="string">&quot;LABEL1&quot;</span> LABEL2=<span class="string">&quot;LABEL2&quot;</span></span></span><br><span class="line"><span class="comment"># 换行多个</span></span><br><span class="line"><span class="keyword">LABEL</span><span class="bash"> LABEL1=<span class="string">&quot;LABEL1&quot;</span> \</span></span><br><span class="line"><span class="bash">      LABEL2=<span class="string">&quot;LABEL2&quot;</span></span></span><br><span class="line">      LABEL3=<span class="string">&quot;LABEL3&quot;</span></span><br></pre></td></tr></table></figure></li>
</ul>
<hr>
<ul>
<li><span style="color:green;">EXPOSE</span>  声明服务内监听的端口，可以指定端口和协议，如果不指定协议默认使用TCP协议。实际上，并没有发布或开放对应端口，仅仅声明要开放的端口。一般写在Dockerfile末尾进行声明，类似一行注释文档。使用docker inspect 容器id可见<h6 id="语法-4"><a href="#语法-4" class="headerlink" title="语法:"></a>语法:</h6><span style="color:#8B008B;">EXPOSE</span> <span style="color:#CD5555;">&lt;port&gt; [&lt;port&gt;/&lt;protocol&gt;…]</span><h6 id="示例：-4"><a href="#示例：-4" class="headerlink" title="示例："></a>示例：</h6><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 声明53端口的dns服务</span></span><br><span class="line"><span class="keyword">EXPOSE</span> <span class="number">53</span>/udp</span><br><span class="line"><span class="comment"># 声明80端口的http服务</span></span><br><span class="line"><span class="keyword">EXPOSE</span> <span class="number">80</span>/tcp</span><br><span class="line"><span class="comment"># 同时开放80端口同时开放udp和tcp协议</span></span><br><span class="line"><span class="keyword">EXPOSE</span> <span class="number">80</span>/tcp</span><br><span class="line"><span class="keyword">EXPOSE</span> <span class="number">80</span>/udp</span><br></pre></td></tr></table></figure></li>
</ul>
<hr>
<ul>
<li><span style="color:green;">COPY</span> 从构建的上下文路径中拷贝文件到指定目录，复制源基于构建上下文的相对路径，支持使用通配符匹配复制.来源如果是文件夹，表示的是复制文件夹下的全部内容。目标文件夹如果使用相对路径表示相对WORKDIR目录<h6 id="语法-5"><a href="#语法-5" class="headerlink" title="语法:"></a>语法:</h6><span style="color:#8B008B;">COPY</span> <span style="color:#CD5555;">[–chown=&lt;user&gt;:&lt;group&gt;]\ [“&lt;src&gt;“,… “&lt;dest&gt;“]</span><h6 id="示例：-5"><a href="#示例：-5" class="headerlink" title="示例："></a>示例：</h6><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 复制上下文目录的所有文件到root目录</span></span><br><span class="line"><span class="keyword">COPY</span><span class="bash"> ./ /root/</span></span><br><span class="line"><span class="comment"># 复制上下文目录下的tar包到root目录</span></span><br><span class="line"><span class="keyword">COPY</span><span class="bash"> *.tar /root/</span></span><br><span class="line"><span class="comment"># 复制文件名test开头的文件到root目录</span></span><br><span class="line"><span class="keyword">COPY</span><span class="bash"> <span class="built_in">test</span>* /root/</span></span><br><span class="line"><span class="comment"># 复制start.sh到WORKDIR/shell目录</span></span><br><span class="line"><span class="keyword">COPY</span><span class="bash"> start.sh shell/</span></span><br><span class="line"><span class="comment"># 复制文件指定复制文件后的属主和数组为www-data(很少用,一般启动容器时指定)</span></span><br><span class="line"><span class="keyword">COPY</span><span class="bash"> --chown=www-data:www-data ./code /home/www-data/</span></span><br></pre></td></tr></table></figure></li>
</ul>
<hr>
<ul>
<li><span style="color:green;">ENTRYPOINT</span> 容器启动默认执行的指令<h6 id="语法-6"><a href="#语法-6" class="headerlink" title="语法:"></a>语法:</h6><span style="color:#8B008B;">ENTRYPOINT</span> <span style="color:#CD5555;">[“executable”, “param1”, “param2”]</span><h6 id="示例：-6"><a href="#示例：-6" class="headerlink" title="示例："></a>示例：</h6><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 容器启动是启动nginx作为1号进程</span></span><br><span class="line"><span class="keyword">ENTRYPOINT</span><span class="bash"> [<span class="string">&quot;top&quot;</span>, <span class="string">&quot;-b&quot;</span>]</span></span><br></pre></td></tr></table></figure></li>
</ul>
<hr>
<ul>
<li><span style="color:green;">WORKDIR</span> 设置工作目录，如果目录不存在则创建。如果提供的是相对路径则是相对上次WORKDIR设置的路径<h6 id="语法-7"><a href="#语法-7" class="headerlink" title="语法:"></a>语法:</h6><span style="color:#8B008B;">WORKDIR</span> <span style="color:#CD5555;">/path/to/workdir</span><h6 id="示例：-7"><a href="#示例：-7" class="headerlink" title="示例："></a>示例：</h6><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">WORKDIR</span><span class="bash"> /home/www-data</span></span><br></pre></td></tr></table></figure></li>
</ul>
<hr>
<ul>
<li><span style="color:green;">CMD</span> 指定启动容器时默认执行的命令<h6 id="语法-8"><a href="#语法-8" class="headerlink" title="语法:"></a>语法:</h6><span style="color:#8B008B;">CMD</span> <span style="color:#CD5555;">[“executable”,”param1”,”param2”]</span><h6 id="示例：-8"><a href="#示例：-8" class="headerlink" title="示例："></a>示例：</h6><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 启动容器是打印一条信息</span></span><br><span class="line"><span class="keyword">CMD</span><span class="bash"> <span class="built_in">echo</span> <span class="string">&quot;容器启动啦&quot;</span></span></span><br><span class="line"><span class="comment"># 打印nginx帮助信息</span></span><br><span class="line"><span class="keyword">CMD</span><span class="bash"> [<span class="string">&quot;nginx&quot;</span>, <span class="string">&quot;-h&quot;</span>]</span></span><br></pre></td></tr></table></figure></li>
</ul>
<p>二、构建命令</p>
<h6 id="语法-9"><a href="#语法-9" class="headerlink" title="语法:"></a>语法:</h6><p> <span style="color:#8B008B;">docker build</span> <span style="color:#CD5555;">[OPTIONS] PATH | URL | -</span></p>
<p>docker通过build命令读取Dockerfile和上下文构建Docker镜像。构建的上下文可以使相对或绝对路径，也可以是一个URL。其他常用选项有</p>
<ul>
<li><span style="color:green;">-f</span>: 指定构建文件，默认是文件是当前目录的名称为Dockerfile的文件</li>
<li><span style="color:green;">-t</span>: 指定镜像的名称和标签</li>
<li><span style="color:green;">–label</span>: 为镜像打标签</li>
<li><span style="color:green;">–no-cache</span>: 构建过程不使用层缓存</li>
<li><span style="color:green;">–rm</span>: 构建成功后删除掉中间容器</li>
<li><span style="color:green;">–target</span>: 指定最终构建阶段名称，针对分多阶段构建的Dockerfile</li>
</ul>
<p>其他选项用的很少或者基本用不上，不再过多介绍，更多选线参考<a target="_blank" rel="noopener" href="https://docs.docker.com/engine/reference/commandline/build/">官方文档</a></p>
<p>构建示例如下：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 当前环境作为上下文构建镜像</span></span><br><span class="line">docker build -t foo:version_1.0 .</span><br><span class="line"><span class="comment"># 指定构建文件</span></span><br><span class="line">docker build -t foo:version_1.0 -f ./Dockerfile.dev .</span><br><span class="line"><span class="comment"># 指定构建过程的上下文</span></span><br><span class="line">docker build -t foo:version ./context_resource</span><br><span class="line"><span class="comment"># 分阶段构建的构建文件，构建TEST过程作为最终镜像</span></span><br><span class="line">docker build -t foo:version_1.0 --target TEST .</span><br><span class="line"><span class="comment"># 分阶段构建的构建文件，删除中间镜像</span></span><br><span class="line">docker build --rm -t foo:version_1.0 .</span><br></pre></td></tr></table></figure>



<p>三、 Docker分层容器</p>
<p>一个Docker镜像是有多个层构成的，每一层代表Dockerfile的一条指令，最后一层是可写层，其它层都是只读层。前一层和后一层的仅仅保存差异。比如下层镜像删除了一个文件，而上层镜像依然可以读取，并且删除下层的文件不会让总体积更小。基于镜像创建一个容器，本质是在给镜像增加了一层作为可写层，容器内的任意文件读写都针对可写层。当容器被删除时，可写层被删除，镜像原有的镜像层保持不变。所以，每个容器堆文件的写入是在独立的可写层中。而多个容器共享底层镜像的只读层。这就是为什么当有基于镜像创建的容器时，无法删除镜像的原因。容器内对文件的读取和修改采用写时复制的(CoW)方式。拿修改系统<code>/etc/hosts</code>文件举例，当在可写层对hosts文件进行读取时，直接使用镜像上层文件进行读取。而当堆<code>/etc/hosts</code>文件进行修改，才会将hosts文件复制到可写层。总之，一个镜像分为多层，下层采用写时复制的方式使用上层文件以缩减当前层级的体积。</p>
<img src="/images/dockerfile-build/sharing-layers.jpg" alt="sharing-layers" style="zoom:100%;margin-left:0px;" />

<p>四、分步构建</p>
<p>在v1.75之前，Dockerfile文件只能写一个镜像的构建脚本，这样就带来几个问题。</p>
<ol>
<li>镜像层级和体积增多<br>一个Docker镜像存在多层，每一层互相隔离。这就导致无法通过删除容器内文件来达到缩减层级和镜像体积的目的。一般来说，我们使用先构建一个镜像，将中间镜像的文件拷贝到Dockerfile的上下文，然后继续编译。这种方式为了达到自动化，需要写两个Dockerfile和一个shell脚本。一方面减少了层级和体积，另一方面能够加速构建的过程</li>
<li>Dockerfile可读性不高<br>Dockerfile中每个RUN指令都会创建一个新的镜像层。确切的说是对镜像本身环境有影响的Dockerfile指令都会创建新层。比如COPY, RUN, ENV等命令会创建新增，而LABEL,CMD等仅修改镜像元数据的命令则不会产生新层。这就意味着要想最终通过删除文件缩减容器体积，在最终删除构建文件前，只能使用一个RUN命令。如果分成多个RUN，最后删除文件操作也无法删除之前层级的文件，导致镜像体积增大。</li>
</ol>
<p>好在，Docker从v17.05开始支持多阶段构建。一个Dockerfile可以分多个阶段构建。后面的构建阶段可以引用、复制前面构建完成的镜像内的文件。下面的例子，演示了通过分布构建设置alpine镜像的时区为<code>Asia/shanghai</code></p>
<figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> alpine:latest AS BUILD_ONE</span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> sed -i <span class="string">&#x27;s/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g&#x27;</span> /etc/apk/repositories</span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> apk add --update-cache tzdata</span></span><br><span class="line"><span class="keyword">FROM</span>  alpine:latest</span><br><span class="line"><span class="keyword">COPY</span><span class="bash"> --from=BUILD_ONE /usr/share/zoneinfo/Asia/Shanghai /etc/localtime</span></span><br></pre></td></tr></table></figure>

<p>首先，通过第0层镜像安装tzdata，得到时区文件。之后将时区文件复制到最终镜像中。容器体积仅仅增加localtime文件大小。因此分层构建经常用于缩减镜像体积。</p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




  <nav class="pagination">
    <a class="extend prev" rel="prev" href="/page/3/"><i class="fa fa-angle-left" aria-label="上一页"></i></a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/3/">3</a><span class="page-number current">4</span><a class="page-number" href="/page/5/">5</a><span class="space">&hellip;</span><a class="page-number" href="/page/22/">22</a><a class="extend next" rel="next" href="/page/5/"><i class="fa fa-angle-right" aria-label="下一页"></i></a>
  </nav>

</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 2021 – 
  <span itemprop="copyrightYear">2022</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">山丘之王</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/pisces/" rel="noopener" target="_blank">NexT.Pisces</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <script src="https://cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script>

  





  





</body>
</html>
